#define WAVE_FORMAT_PCM         ((short)0x0001)
#define WAVE_FORMAT_IEEE_FLOAT  ((short)0x0003)
#define WAVE_FORMAT_ALAW        ((short)0x0006)
#define WAVE_FORMAT_MULAW       ((short)0x0007)
#define WAVE_FORMAT_EXTENSIBLE  ((short)0xFFFE)

typedef struct {
	char header[4];
	int wav_size;
} riff_chunk;

typedef struct {
	char header[4];
	int chunk_size;
} junk_chunk;

typedef struct {
	char header[4];
	int chunk_size;
} fllr_chunk;

typedef struct {
	char header[4];
	int chunk_size;
	short audio_format;
	short num_channels;
	int sample_rate;
	int byte_rate;
	short sample_alignment;
	short bit_depth;
} fmt_chunk;

typedef struct {
	short extension_size;
	short valid_bits_per_sample;
	int channel_mask;
	char guid[16];
} fmt_extension;

typedef struct {
	char header[4];
	int data_size;
	int sample_num;
} fact_chunk;

typedef struct {
	char header[4];
	int chunk_size;
	int version;
	int timestamp;
	void* peak_pos1;
	void* peak_pos2;
} peak_chunk;

typedef struct {
	char header[4];
	int data_bytes;
} data_chunk;

typedef struct {
	riff_chunk riff;
	char wave_header[4];
	char pad[4096];
} wav_header_ext;

typedef struct {
	// RIFF Header, contains "RIFF"
	char riff_header[sizeof(int) / sizeof(char)];
	// Size of the wav portion of the file, which follows the first 8 bytes.
	// File size - 8
	int wav_size;
	// Contains "WAVE"
	char wave_header[sizeof(int) / sizeof(char)];

	// Format Header, contains "fmt " (includes trailing space)
	char fmt_header[sizeof(int) / sizeof(char)];
	// Should be 16 for PCM
	int fmt_chunk_size;
	// Should be 1 for PCM. 3 for IEEE Float
	short audio_format;
	short num_channels;
	int sample_rate;
	// Number of bytes per second. sample_rate * num_channels * Bytes Per Sample
	int byte_rate;
	// num_channels * Bytes Per Sample
	short sample_alignment;
	// Number of bits per sample
	short bit_depth;
	// Optional field, depend on fmt_chunk_size
	// short extension_size;
	// short valid_bits_per_sample;
	// int channel_mask;
	// char guid[16];
	char data_header[sizeof(int) / sizeof(char)];
	// Number of bytes in data.
	// Number of samples * num_channels * sample byte size
	int data_bytes;
} wav_header;

struct wavdata {
	float** data;
	int num_channels;
	int samples_per_channel;
	int samplerate;
	int bit_depth;
};
struct wavdata* getdatafromWAV(char* in_file);
void writeWAV(char* out_file, struct wavdata* obj);
void wavdataDestory(struct wavdata* obj);
struct wavdata* initwavdata(int num_channels, int samples_per_channel, int samplerate, int bit_depth);
void writeWAV_float(char* out_file, struct wavdata* obj);